package redisenum

import (
	"context"
	"fmt"
	"gitee.com/worklz/yunj-blog-go-micro-common/enum"
	"gitee.com/worklz/yunj-blog-go-micro-common/redis"
)

type GroupInterface interface {
	enum.EnumInterface[int]
	AllConstAttrs() map[int]map[string]any
}

type Group struct {
	enum.Enum[int]
	GroupInstance GroupInterface // 继承使用
}

// 获取当前Group实例，允许继承设置
func (g *Group) GetGroupInstance() GroupInterface {
	if g.GroupInstance != nil {
		return g.GroupInstance
	}
	return g
}

// 存储已经创建的实例
var groupInstanceCache = make(map[int]*Group)

// 根据value获取枚举
func GroupByValue(value int) *Group {
	if instance, exists := groupInstanceCache[value]; exists {
		return instance
	}
	e := &Group{}
	enum.SetEnumInstance(&e.Enum, e, value)
	groupInstanceCache[value] = e
	return e
}

var GroupEnum *Group = func() *Group {
	e := &Group{}
	enum.SetEnumInstance(&e.Enum, e)
	return e
}()

// 删除缓存
// .GroupByValue(示例：redisenum.ARTICLE).DelCache()
func (rg *Group) DelCache() error {
	allRedisKeys := []string{}
	// 获取当前分组的所有redis key实例
	keys := rg.GetKeyInstances()
	ctx := context.Background()
	for _, key := range keys {
		keySuffix := key.GetAttr("keySuffix")
		if _, ok := KeySubffixCheck(keySuffix); ok {
			// 有后缀的
			pattern := fmt.Sprintf("%s*", key.GetStringValue())
			redisKeys, err := redis.Keys(ctx, pattern)
			if err != nil {
				return err
			}
			allRedisKeys = append(allRedisKeys, redisKeys...)
		} else {
			// 没有后缀的
			allRedisKeys = append(allRedisKeys, key.GetStringValue())
		}
	}
	if len(allRedisKeys) == 0 {
		return nil
	}
	// 进行删除
	return redis.Del(context.Background(), allRedisKeys)
}

// 获取当前分组的redis key实例
func (rg *Group) GetKeyInstances() []KeyInterface {
	keys := []KeyInterface{}
	keys = rg.getKeyInstances(rg.GetGroupInstance().GetValue(), keys)
	return keys
}

// 获取指定分组的所有keys
func (rg *Group) getKeyInstances(group int, keys []KeyInterface) []KeyInterface {
	attrs, exists := rg.GetGroupInstance().AllConstAttrs()[group]
	if !exists {
		return keys
	}
	var keyBaseInstance KeyInterface
	if kBaseInstance, exists := attrs["keyBaseInstance"]; exists {
		if kBaseInstance, ok := kBaseInstance.(KeyInterface); ok {
			keyBaseInstance = kBaseInstance
		}
	}
	if keyBaseInstance == nil {
		keyBaseInstance = KeyEnum
	}
	if rgKeys, exists := attrs["keys"]; exists {
		if keyConsts, ok := rgKeys.([]string); ok {
			for _, k := range keyConsts {
				if kVal, ok := keyBaseInstance.IsValue(k); ok {
					keys = append(keys, keyBaseInstance.ByValue(kVal))
				}
			}
		}
	}
	// 遍历parent
	if rgParent, exists := attrs["parent"]; exists {
		if parent, ok := rgParent.(int); ok {
			return rg.getKeyInstances(parent, keys)
		}
	}
	return keys
}

// 获取当前分组的所有redis key常量
func (rg *Group) GetAllRedisKeyConsts() []string {
	allRedisKeyConsts := []string{}
	allRedisKeyConsts = rg.handleAllRedisKeyConsts(rg.GetGroupInstance().GetValue(), allRedisKeyConsts)
	return allRedisKeyConsts
}

// 处理指定分组的所有keys，合并到总的keys内
// aooend会产生一个新切片，所以此处要用返回接收接片结果
func (rg *Group) handleAllRedisKeyConsts(group int, allRedisKeyConsts []string) []string {
	attrs, exists := rg.GetGroupInstance().AllConstAttrs()[group]
	if !exists {
		return allRedisKeyConsts
	}
	if rgKeys, exists := attrs["keys"]; exists {
		if keys, ok := rgKeys.([]string); ok {
			allRedisKeyConsts = append(allRedisKeyConsts, keys...)
		}
	}
	// 遍历parent
	if rgParent, exists := attrs["parent"]; exists {
		if parent, ok := rgParent.(int); ok {
			return rg.handleAllRedisKeyConsts(parent, allRedisKeyConsts)
		}
	}
	return allRedisKeyConsts
}
